{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1 requests 模块，用于简化HTTP请求的发送和响应处理(调用API、下载文件、处理复杂的会话管理)\n",
    "安装：pip install requests"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2 基础使用方法  \n",
    "1 发送POST请求  \n",
    "在接口测试中，POST请求经常用于发送数据。假设测试一个登录接口，需要传递用户名和密码作为请求参数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "200\n",
      "{\"ret\": 1, \"msg\": \"\\u7528\\u6237\\u540d\\u6216\\u5bc6\\u7801\\u9519\\u8bef\"}\n"
     ]
    }
   ],
   "source": [
    "import requests\n",
    "\n",
    "# 设置请求的URL和参数\n",
    "url = 'http://127.0.0.1:80/api/mgr/signin'\n",
    "headers = {'Content-Type': 'applicaiton/x-www-form-urlencoded'}\n",
    "data = {'username': 'Salesys', 'password': 'Password:'}\n",
    "\n",
    "# 发起POST请求\n",
    "response = requests.post(url, headers=headers, data=data)\n",
    "\n",
    "# 查看响应状态码和内容\n",
    "print(response.status_code) # 200表示请求成功\n",
    "print(response.text) # 返回服务器响应的文本内容"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2 GET 请求常用于获取服务器资源，如获取商品列表。我们可以传递查询参数，服务器根据参数返回特定的数据."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'ret': 302, 'msg': '未登录', 'redirect': '/mgr/sign.html'}\n"
     ]
    }
   ],
   "source": [
    "url = 'http://127.0.0.1:80/api/mgr/customers'\n",
    "params = {'name': '张三'}\n",
    "\n",
    "response = requests.get(url, params=params)\n",
    "\n",
    "# 输出返回的JSON数据\n",
    "print(response.json())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3 POST 与 GET 请求的区别  在实际的项目中，选择POST还是GET请求取决于数据传递的需求：  \n",
    "- GET请求：用于从服务器获取数据，查询参数通过URL传递，适用于获取资源。  \n",
    "- PSOT请求：用于提交数据到服务器，参数在请求中，适用于数据提交或修改。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 4数据传递格式\n",
    "1表单提交与JSON数据\n",
    "POST 请求的数据传输方式主要有两种：表单数据和JSON数据。\n",
    "- 表单提交："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = {'username': 'testuser', 'password': 'testpass'}\n",
    "response = requests.post(url, data=data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- JSON提交："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "json_data = {'username': 'testuser', 'password': 'testpass'}\n",
    "response = requests.post(url, json=json_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "不同的接口通常有特定的数据格式要求，测试时需依据接口文档确定数传输方式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 5会话管理与持久性连接\n",
    "在一些需要多次请求的场景下，使用会话对象 Session 可以管理持久性连接，避免重复登陆等频繁操作。尤其是涉及用户登录、会话保持的场景， Session 的使用至关重要。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建会话对象\n",
    "session = requests.Session()\n",
    "\n",
    "# 使用会话对象进行登录\n",
    "login_url = 'http://127.0.0.1:80/api/mgr/signin'\n",
    "session.post(login_url, data={'username': 'salesys', 'password': 'Password:'})\n",
    "\n",
    "# 登录后，访问受保护的资源\n",
    "protected_url = 'http://127.0.0.1:80/protected'\n",
    "response = session.get(protected_url)\n",
    "\n",
    "print(response.text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 6处理响应结果\n",
    "在自动化测试中，我们不仅关心接口的响应状态码，还需要处理接口返回的数据格式。requests 支持多种返回格式：\n",
    "- 文本类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(response.text) # 返回文本格式的响应"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- JSON 类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(response.json()) # 解析JSON响应"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 二进制内容"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(response.content) # 获取二进制内容，如图片或者文件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "此外，遇到编码问题时，可以使用response.encoding或通过手动解码方式来处理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 7应对 HTTPS 证书验证\n",
    "在测试 HTTPS 接口时，可能会遇到证书验证错误，尤其是在开发环境中。可以通过以下方式禁用证书验证："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "response = requests.get(url, verify=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 8错误处理与异常捕获\n",
    "requests 提供了强的的异常处理机制，在测试过程中可以捕获网络错误或超时问题："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    response = requests.get(url, timeout=5)\n",
    "    response.raise_for_status() # 检查请求是否成功\n",
    "except requests.exceptions.HTTPError as http_err:\n",
    "    print(f'HTTP error occurred: {http_err}')\n",
    "except requests.exceptions.RequestException as err:\n",
    "    print(f'Other error occured: {err}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 参考资料\n",
    "[Requests 官方文档](https://docs.python-requests.org/en/latest/)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
